/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tletlis.controller;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import tletlis.network.*;

/**
 * A class that handles updating of the Tetlis game.
 * It recieves data from a server client and transmitts new data back to the
 * client. The update interval is decided by the control class.
 * @author David
 */
public class Update extends Thread {
    /**
     * Boolean indicating if the current game is a multi-player game.
     */
    private boolean isMultiPlay;

    /**
     * The controller communicating with the view.
     */
    private Controller control;

    /**
     * The client being used to communicate over the network.
     */
    private Client client;

    //Boolean telling if the instance runs a server or not.
    private boolean isServer;

    /**
     * The server being used to handle the network.
     */
    private Server server;

    /**
     * The server port to be used for network communication.
     */
    private int serverPort = 15555;

    /**
     * The name of the player
     */
    private String name;
    
    /**
     * Constructor for single player games.
     */
    public Update(String name){
        super("update");
        control = new Controller(250,10,500);
        isMultiPlay = false;
        control.setName(name);
        start();
    }

    /**
     * Constructor for multi-player games.
     * Sets computers ip-address on gui.
     * @param spelare The number of players intended to play against each other.
     * @param isServer Indicates if the player will act as host/server.
     * @param serverIp The IP of the host/server.
     */
    public Update(int spelare, boolean isHost, String serverIp, String name){
        super("update");
        if (isHost) {
            isServer = isHost;
            server = new Server(serverPort,spelare);
            client = new Client("127.0.0.1", serverPort);


        }
        else {
            client = new Client(serverIp, serverPort);
        }
        client.connect();
        control = new Controller(250,10,500);
        isMultiPlay = true;
        control.setName(name);

        //if player is host add his ip to the gui
          if(isHost){
            MyIp  myIp= new MyIp();
            String ip= myIp.getMyIp();
            control.setIpLabel(ip);
          }
        this.name=name;
        start();
        
    }

    /**
     * Method for updating the game and the network.
     *
     * If a multiplayer game is created the game waits for the other player to
     * connect to the server. When the connection is established a starting 
     * method on the controller is called and when that method is done the
     * updating process starts.
     *
     * The updating process fetches network input and communicates it to the
     * controller.
     * The controller returns an int which is sent to the oponent.
     * Then the thread sleeps a number of ms according to what level has been
     * reached in the game.
     */
    @Override
    public void run() {
        //If multiplayer game. Send player name to opponent and wait for
        //opponent player name
        if(isMultiPlay){
            

            String oponentName = "";
            while (true) {
                oponentName = client.updateNetwork();
                if (!oponentName.equals("0")) {
                    client.send(name);
                    break;
                }
            }
            while (true) {
                oponentName = client.updateNetwork();
                if(!oponentName.equals("0")) {
                    control.setOponentName(oponentName);
                    break;
                }
            }

        }

        // start the updating process
        while(true) {

            if (isMultiPlay) {
                String myRows = "0";
                String oponentRows = "0";
                oponentRows = client.updateNetwork();
                if (oponentRows.equals("-1")) {
                    try {
                        myRows = Integer.toString(control.updateGame(-1));
                        break;
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(Update.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IOException ex) {
                        Logger.getLogger(Update.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                else if (oponentRows.equals("0")) {
                    try {
                        myRows = Integer.toString(control.updateGame(0));
                        if (myRows.equals("-1")){
                            client.send(myRows);
                            break;
                        }
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(Update.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IOException ex) {
                        Logger.getLogger(Update.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    client.send(myRows);
                }
                else {
                    try {
                        myRows = Integer.toString(control.updateGame(Integer.parseInt(oponentRows)));
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(Update.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IOException ex) {
                        Logger.getLogger(Update.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    client.send(myRows);
                }
            }
            else {
                try {
                    if (control.updateGame(0) == -1) {
                        break;
                    }
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(Update.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(Update.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            try {
                sleep(control.getSpeed());

            } catch (InterruptedException e) {

            }
        }
    }
}